#ifndef EMS_UTILS_CONFIG_H
#define EMS_UTILS_CONFIG_H

#include <cstdint>
#include <string>
#include <map>
#include <vector>
#include <memory>

namespace ems {
namespace utils {

class Json;

struct DeviceConfig {
    std::string id;
    std::string name;
    std::string type;
    std::string protocol;
    std::map<std::string, std::string> connection;
    std::string protocolConfig;
    int pollInterval;
    int uploadInterval;   // 兼容：设备级上报间隔（秒）；<=0 表示使用系统默认
    bool enabled;

    // MQTT sync related fields
    int deviceType;           // 设备类型（用于MQTT同步）
    std::string deviceSn;     // 设备序列号（用于MQTT同步）
    int onlineState;          // 在线状态（0=离线，1=在线）
    int subDeviceCount;       // 子设备数量（目前暂不支持）

    // 物模型（如 bms/pcs/alarm）配置：按模型设置上报频率（秒）与启用状态
    struct ModelConfig {
        bool enabled{true};
        int uploadIntervalSec{-1}; // <=0 表示使用系统默认
        std::string deviceSn;
        int deviceType{0};
        std::string deviceName;
        int index{1};
    };
    std::map<std::string, ModelConfig> models; // key: 模型名称，例如 "bms"、"pcs"、"alarm"
};

struct MqttConfig {
    std::string host;
    int port;
    bool useTls;
    std::string caFile;
    std::string certFile;
    std::string keyFile;
    // Client fields
    std::string clientId;
    std::string deviceSn;
    std::string deviceType;
    std::string username;
    std::string password;
    int keepAlive;
    bool cleanSession;
    int qos;
    bool retained;
    std::map<std::string, std::string> topics;
    // Optional security
    std::string signMethod;          // e.g. hmacsha256
    std::string deviceTypeSecret;    // used for register/login signature if required
};

struct ModbusConfig {
    // Modbus TCP配置
    int defaultTcpTimeout;
    int defaultTcpPort;
    int tcpRetryCount;
    int tcpRetryInterval;
    int tcpReadTimeout;
    int tcpWriteTimeout;
    int maxConcurrentConnections;
    
    // Modbus RTU配置
    int defaultBaudrate;
    std::string defaultParity;
    int defaultDataBits;
    int defaultStopBits;
    int rtuTimeout;
    int rtuRetryCount;
    int rtuRetryInterval;
    int rtuReadTimeout;
    int rtuWriteTimeout;
    int frameDelay;
    int responseTimeout;
    
    // 通用配置
    int pollInterval;
    int errorThreshold;
    int reconnectDelay;
    int maxRegisterCount;
    bool enableLogging;
    std::string logLevel;
};

struct SystemConfig {
    std::string logLevel;
    std::string logFile;
    std::string maxLogSize;
    int dataCacheSize;
    int threadPoolSize;
    int retryTimes;
    int retryInterval;
    int batchSize;
    int queueMaxSize;
    bool batchUpload;
    int uploadInterval;
};

enum class TimeOfUseTier {
    Peak,
    Flat,
    Valley
};

struct TimeRange {
    int startMinute{0};
    int endMinute{0};
    bool crossesMidnight{false};

    bool contains(int minute) const {
        if (!crossesMidnight) {
            return minute >= startMinute && minute < endMinute;
        }
        return minute >= startMinute || minute < endMinute;
    }
};

struct TimeOfUseSchedule {
    std::vector<TimeRange> peak;
    std::vector<TimeRange> flat;
    std::vector<TimeRange> valley;
};

struct MonthlyTariff {
    int month{0};
    double peak{0.0};
    double flat{0.0};
    double valley{0.0};
};

struct TimeOfUseTable {
    std::string unit;
    TimeOfUseSchedule schedule;
    std::map<int, MonthlyTariff> monthly;
    bool loaded{false};
};

struct DispatchConfig {
    bool enabled{true};                // 是否启用调度策略
    double pvFeedPrice{0.453};        // 光伏上网电价（元/kWh）
    double storageChargePrice{0.0};   // 储能历史充电均价（元/kWh）
    double gridPricePeak{0.0};        // 当日峰段最高电价（元/kWh）
    double criticalLoadKw{0.0};       // 关键负载保底功率（kW）
};

class Config {
public:
    static Config& getInstance();
    
    bool load(const std::string& configPath);
    bool saveMqttIdentity(const std::string& deviceSn, const std::string& clientId);
    
    const std::vector<DeviceConfig>& getDevices() const { return devices_; }
    const MqttConfig& getMqtt() const { return mqtt_; }
    const ModbusConfig& getModbus() const { return modbus_; }
    const SystemConfig& getSystem() const { return system_; }
    bool hasTimeOfUsePrice() const { return timeOfUsePrices_.loaded; }
    double getTimeOfUsePrice(std::int64_t timestampSeconds) const;
    double getTimeOfUsePeakPrice(std::int64_t timestampSeconds) const;
    bool isTimeOfUsePeakPeriod(std::int64_t timestampSeconds) const;
    const DispatchConfig& getDispatch() const { return dispatch_; }
    void setDispatchEnabled(bool enabled);
    bool reloadDevices();
    
    std::string getString(const std::string& key, const std::string& defaultValue = "") const;
    int getInt(const std::string& key, int defaultValue = 0) const;
    bool getBool(const std::string& key, bool defaultValue = false) const;

private:
    Config() = default;
    ~Config() = default;
    Config(const Config&) = delete;
    Config& operator=(const Config&) = delete;
    
    bool loadDevices(const std::string& configPath);
    bool loadMqtt(const std::string& configPath);
    bool loadModbus(const std::string& configPath);
    bool loadSystem(const std::string& configPath);
    bool loadTimeOfUsePrices(const std::string& configPath);
    bool resolveTimeOfUseContext(std::int64_t timestampSeconds,
                                 MonthlyTariff& tariff,
                                 TimeOfUseTier& tier,
                                 int& minuteOfDay) const;
    
    std::vector<DeviceConfig> devices_;
    MqttConfig mqtt_;
    ModbusConfig modbus_;
    SystemConfig system_;
    TimeOfUseTable timeOfUsePrices_;
    DispatchConfig dispatch_;
    std::map<std::string, std::string> additionalConfig_;
    std::string configRoot_;
};

}  // namespace utils
}  // namespace ems

#endif  // EMS_UTILS_CONFIG_H
